import { compileToFunction } from "./compiler/index";
import { mountComponent } from "./lifecycle";
import { initState } from "./state";

export function initMixin(Vue) {
  Vue.prototype._init = function (options) {
    // console.log(option);

    // 我们使用的vue的时候 $nextTick $data $attr...
    const vm = this;
    vm.$options = options; //将用户的选项挂载到实例上

    // 初始化状态，处理传递过来的选项
    // 初始化data、计算属性、watch
    initState(vm);

    if (options.el) {
      vm.$mount(options.el); // 实现数据的挂载
    }
  };

  Vue.prototype.$mount = function (el) {
    const vm = this;
    el = document.querySelector(el);
    let ops = vm.$options;
    // 如果写了render函数先处理render
    if (!ops.render) {
      // 没有render看一下是否写了template，没写再用外部的template
      let template;
      if (!ops.template && el) {
        // 没有写模板 但是写了el （外部template）
        template = el.outerHTML;
      } else {
        // 写了template，el也得有，因为内部的模板要指定挂载到哪一个el元素上(不确定)
        // （选项内部的template）
        if (el) {
          template = ops.template;
        }
      }

      // 写了template就用写了的template
      if (template && el) {
        // 对模板进行编译，将模板编译为render函数
        // runtime和runtimewithcompiler 多了compileToFunction函数
        const render = compileToFunction(template);
        ops.render = render; // jsx最终会被编译成h('xxx)
      }
    }

    // 最终取到ops上的render方法ops.render
    // console.log(ops.render);
    mountComponent(vm, el); // 组件的挂载
  };
}
